home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_023 / ver30 / buffer.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  382 lines

  1. /*
  2.  * Name:    MicroEMACS
  3.  *        Buffer handling.
  4.  * Version:    30
  5.  * Last edit:    17-Feb-86
  6.  * By:        rex::conroy
  7.  *        decvax!decwrl!dec-rhea!dec-rex!conroy
  8.  */
  9. #include    "def.h"
  10.  
  11. /*
  12.  * Attach a buffer to a window. The
  13.  * values of dot and mark come from the buffer
  14.  * if the use count is 0. Otherwise, they come
  15.  * from some other window.
  16.  */
  17. usebuffer(f, n, k)
  18. {
  19.     register BUFFER    *bp;
  20.     register WINDOW    *wp;
  21.     register int    s;
  22.     char        bufn[NBUFN];
  23.  
  24.     if ((s=ereply("Use buffer: ", bufn, NBUFN)) != TRUE)
  25.         return (s);
  26.     if ((bp=bfind(bufn, TRUE)) == NULL)
  27.         return (FALSE);
  28.     if (--curbp->b_nwnd == 0) {        /* Last use.        */
  29.         curbp->b_dotp  = curwp->w_dotp;
  30.         curbp->b_doto  = curwp->w_doto;
  31.         curbp->b_markp = curwp->w_markp;
  32.         curbp->b_marko = curwp->w_marko;
  33.     }
  34.     curbp = bp;                /* Switch.        */
  35.     curwp->w_bufp  = bp;
  36.     curwp->w_linep = bp->b_linep;        /* For macros, ignored.    */
  37.     curwp->w_flag |= WFMODE|WFFORCE|WFHARD;    /* Quite nasty.        */
  38.     if (bp->b_nwnd++ == 0) {        /* First use.        */
  39.         curwp->w_dotp  = bp->b_dotp;
  40.         curwp->w_doto  = bp->b_doto;
  41.         curwp->w_markp = bp->b_markp;
  42.         curwp->w_marko = bp->b_marko;
  43.         return (TRUE);
  44.     }
  45.     wp = wheadp;                /* Look for old.    */
  46.     while (wp != NULL) {
  47.         if (wp!=curwp && wp->w_bufp==bp) {
  48.             curwp->w_dotp  = wp->w_dotp;
  49.             curwp->w_doto  = wp->w_doto;
  50.             curwp->w_markp = wp->w_markp;
  51.             curwp->w_marko = wp->w_marko;
  52.             break;
  53.         }
  54.         wp = wp->w_wndp;
  55.     }
  56.     return (TRUE);
  57. }
  58.  
  59. /*
  60.  * Dispose of a buffer, by name.
  61.  * Ask for the name. Look it up (don't get too
  62.  * upset if it isn't there at all!). Get quite upset
  63.  * if the buffer is being displayed. Clear the buffer (ask
  64.  * if the buffer has been changed). Then free the header
  65.  * line and the buffer header. Bound to "C-X K".
  66.  */
  67. killbuffer(f, n, k)
  68. {
  69.     register BUFFER    *bp;
  70.     register BUFFER    *bp1;
  71.     register BUFFER    *bp2;
  72.     register int    s;
  73.     char        bufn[NBUFN];
  74.  
  75.     if ((s=ereply("Kill buffer: ", bufn, NBUFN)) != TRUE)
  76.         return (s);
  77.     if ((bp=bfind(bufn, FALSE)) == NULL)    /* Easy if unknown.    */
  78.         return (TRUE);
  79.     if (bp->b_nwnd != 0) {            /* Error if on screen.    */
  80.         eprintf("Buffer is being displayed");
  81.         return (FALSE);
  82.     }
  83.     if ((s=bclear(bp)) != TRUE)        /* Blow text away.    */
  84.         return (s);
  85.     free((char *) bp->b_linep);        /* Release header line.    */
  86.     bp1 = NULL;                /* Find the header.    */
  87.     bp2 = bheadp;
  88.     while (bp2 != bp) {
  89.         bp1 = bp2;
  90.         bp2 = bp2->b_bufp;
  91.     }
  92.     bp2 = bp2->b_bufp;            /* Next one in chain.    */
  93.     if (bp1 == NULL)            /* Unlink it.        */
  94.         bheadp = bp2;
  95.     else
  96.         bp1->b_bufp = bp2;
  97.     free((char *) bp);            /* Release buffer block    */
  98.     return (TRUE);
  99. }
  100.  
  101. /*
  102.  * Display the buffer list. This is done
  103.  * in two parts. The "makelist" routine figures out
  104.  * the text, and puts it in the buffer whoses header is
  105.  * pointed to by the external "blistp". The "popblist"
  106.  * then pops the data onto the screen. Bound to
  107.  * "C-X C-B".
  108.  */
  109. listbuffers(f, n, k)
  110. {
  111.     register int    s;
  112.  
  113.     if ((s=makelist()) != TRUE)
  114.         return (s);
  115.     return (popblist());
  116. }
  117.  
  118. /*
  119.  * Pop the special buffer whose
  120.  * buffer header is pointed to by the external
  121.  * variable "blistp" onto the screen. This is used
  122.  * by the "listbuffers" routine (above) and by
  123.  * some other packages. Returns a status.
  124.  */
  125. popblist()
  126. {
  127.     register WINDOW    *wp;
  128.     register BUFFER    *bp;
  129.  
  130.     if (blistp->b_nwnd == 0) {        /* Not on screen yet.    */
  131.         if ((wp=wpopup()) == NULL)
  132.             return (FALSE);
  133.         bp = wp->w_bufp;
  134.         if (--bp->b_nwnd == 0) {
  135.             bp->b_dotp  = wp->w_dotp;
  136.             bp->b_doto  = wp->w_doto;
  137.             bp->b_markp = wp->w_markp;
  138.             bp->b_marko = wp->w_marko;
  139.         }
  140.         wp->w_bufp  = blistp;
  141.         ++blistp->b_nwnd;
  142.     }
  143.     wp = wheadp;
  144.     while (wp != NULL) {
  145.         if (wp->w_bufp == blistp) {
  146.             wp->w_linep = lforw(blistp->b_linep);
  147.             wp->w_dotp  = lforw(blistp->b_linep);
  148.             wp->w_doto  = 0;
  149.             wp->w_markp = NULL;
  150.             wp->w_marko = 0;
  151.             wp->w_flag |= WFMODE|WFHARD;
  152.         }
  153.         wp = wp->w_wndp;
  154.     }
  155.     return (TRUE);
  156. }
  157.  
  158. /*
  159.  * This routine rebuilds the
  160.  * text in the special secret buffer
  161.  * that holds the buffer list. It is called
  162.  * by the list buffers command. Return TRUE
  163.  * if everything works. Return FALSE if there
  164.  * is an error (if there is no memory).
  165.  */
  166. makelist()
  167. {
  168.     register char    *cp1;
  169.     register char    *cp2;
  170.     register int    c;
  171.     register BUFFER    *bp;
  172.     register LINE    *lp;
  173.     register int    nbytes;
  174.     register int    s;
  175.     char        b[6+1];
  176.     char        line[128];
  177.  
  178.     blistp->b_flag &= ~BFCHG;        /* Blow away old.    */
  179.     if ((s=bclear(blistp)) != TRUE)
  180.         return (s);
  181.     strcpy(blistp->b_fname, "");
  182.     if (addline("C   Size Buffer           File") == FALSE
  183.     ||  addline("-   ---- ------           ----") == FALSE)
  184.         return (FALSE);
  185.     bp = bheadp;                /* For all buffers    */
  186.     while (bp != NULL) {
  187.         cp1 = &line[0];            /* Start at left edge    */
  188.         if ((bp->b_flag&BFCHG) != 0)    /* "*" if changed    */
  189.             *cp1++ = '*';
  190.         else
  191.             *cp1++ = ' ';
  192.         *cp1++ = ' ';            /* Gap.            */
  193.         nbytes = 0;            /* Count bytes in buf.    */
  194.         lp = lforw(bp->b_linep);
  195.         while (lp != bp->b_linep) {
  196.             nbytes += llength(lp)+1;
  197.             lp = lforw(lp);
  198.         }
  199.         itoa(b, 6, nbytes);        /* 6 digit buffer size.    */
  200.         cp2 = &b[0];
  201.         while ((c = *cp2++) != 0)
  202.             *cp1++ = c;
  203.         *cp1++ = ' ';            /* Gap.            */
  204.         cp2 = &bp->b_bname[0];        /* Buffer name        */
  205.         while ((c = *cp2++) != 0)
  206.             *cp1++ = c;
  207.         cp2 = &bp->b_fname[0];        /* File name        */
  208.         if (*cp2 != 0) {
  209.             while (cp1 < &line[1+1+6+1+NBUFN+1])
  210.                 *cp1++ = ' ';        
  211.             while ((c = *cp2++) != 0) {
  212.                 if (cp1 < &line[128-1])
  213.                     *cp1++ = c;
  214.             }
  215.         }
  216.         *cp1 = 0;            /* Add to the buffer.    */
  217.         if (addline(line) == FALSE)
  218.             return (FALSE);
  219.         bp = bp->b_bufp;
  220.     }
  221.     return (TRUE);                /* All done        */
  222. }
  223.  
  224. /*
  225.  * Used above.
  226.  */
  227. itoa(buf, width, num)
  228. register char    buf[];
  229. register int    width;
  230. register int    num;
  231. {
  232.     buf[width] = 0;                /* End of string.    */
  233.     while (num >= 10) {            /* Conditional digits.    */
  234.         buf[--width] = (num%10) + '0';
  235.         num /= 10;
  236.     }
  237.     buf[--width] = num + '0';        /* Always 1 digit.    */
  238.     while (width != 0)            /* Pad with blanks.    */
  239.         buf[--width] = ' ';
  240. }
  241.  
  242. /*
  243.  * The argument "text" points to
  244.  * a string. Append this line to the
  245.  * buffer list buffer. Handcraft the EOL
  246.  * on the end. Return TRUE if it worked and
  247.  * FALSE if you ran out of room.
  248.  */
  249. addline(text)
  250. char    *text;
  251. {
  252.     register LINE    *lp;
  253.     register int    i;
  254.     register int    ntext;
  255.  
  256.     ntext = strlen(text);
  257.     if ((lp=lalloc(ntext)) == NULL)
  258.         return (FALSE);
  259.     for (i=0; i<ntext; ++i)
  260.         lputc(lp, i, text[i]);
  261.     blistp->b_linep->l_bp->l_fp = lp;    /* Hook onto the end    */
  262.     lp->l_bp = blistp->b_linep->l_bp;
  263.     blistp->b_linep->l_bp = lp;
  264.     lp->l_fp = blistp->b_linep;
  265.     if (blistp->b_dotp == blistp->b_linep)    /* If "." is at the end    */
  266.         blistp->b_dotp = lp;        /* move it to new line    */
  267.     return (TRUE);
  268. }
  269.  
  270. /*
  271.  * Look through the list of
  272.  * buffers. Return TRUE if there
  273.  * are any changed buffers. Special buffers
  274.  * like the buffer list buffer don't count, as
  275.  * they are not in the list. Return FALSE if
  276.  * there are no changed buffers.
  277.  */
  278. anycb()
  279. {
  280.     register BUFFER    *bp;
  281.  
  282.     bp = bheadp;
  283.     while (bp != NULL) {
  284.         if ((bp->b_flag&BFCHG) != 0)
  285.             return (TRUE);
  286.         bp = bp->b_bufp;
  287.     }
  288.     return (FALSE);
  289. }
  290.  
  291. /*
  292.  * Search for a buffer, by name.
  293.  * If not found, and the "cflag" is TRUE,
  294.  * create a buffer and put it in the list of
  295.  * all buffers. Return pointer to the BUFFER
  296.  * block for the buffer.
  297.  */
  298. BUFFER    *
  299. bfind(bname, cflag)
  300. register char    *bname;
  301. {
  302.     register BUFFER    *bp;
  303.  
  304.     bp = bheadp;
  305.     while (bp != NULL) {
  306.         if (strcmp(bname, bp->b_bname) == 0)
  307.             return (bp);
  308.         bp = bp->b_bufp;
  309.     }
  310.     if (cflag!=FALSE && (bp=bcreate(bname))!=NULL) {
  311.         bp->b_bufp = bheadp;
  312.         bheadp = bp;
  313.     }
  314.     return (bp);
  315. }
  316.  
  317. /*
  318.  * Create a buffer, by name.
  319.  * Return a pointer to the BUFFER header
  320.  * block, or NULL if the buffer cannot
  321.  * be created. The BUFFER is not put in the
  322.  * list of all buffers; this is called by
  323.  * "edinit" to create the buffer list
  324.  * buffer.
  325.  */
  326. BUFFER    *
  327. bcreate(bname)
  328. register char    *bname;
  329. {
  330.     register BUFFER    *bp;
  331.     register LINE    *lp;
  332.  
  333.     if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
  334.         return (NULL);
  335.     if ((lp=lalloc(0)) == NULL) {
  336.         free((char *) bp);
  337.         return (NULL);
  338.     }
  339.     bp->b_bufp  = NULL;
  340.     bp->b_dotp  = lp;
  341.     bp->b_doto  = 0;
  342.     bp->b_markp = NULL;
  343.     bp->b_marko = 0;
  344.     bp->b_flag  = 0;
  345.     bp->b_nwnd  = 0;
  346.     bp->b_linep = lp;
  347.     strcpy(bp->b_fname, "");
  348.     strcpy(bp->b_bname, bname);
  349.     lp->l_fp = lp;
  350.     lp->l_bp = lp;
  351.     return (bp);
  352. }
  353.  
  354. /*
  355.  * This routine blows away all of the text
  356.  * in a buffer. If the buffer is marked as changed
  357.  * then we ask if it is ok to blow it away; this is
  358.  * to save the user the grief of losing text. The
  359.  * window chain is nearly always wrong if this gets
  360.  * called; the caller must arrange for the updates
  361.  * that are required. Return TRUE if everything
  362.  * looks good.
  363.  */
  364. bclear(bp)
  365. register BUFFER    *bp;
  366. {
  367.     register LINE    *lp;
  368.     register int    s;
  369.     
  370.     if ((bp->b_flag&BFCHG) != 0        /* Changed.        */
  371.     && (s=eyesno("Discard changes")) != TRUE)
  372.         return (s);
  373.     bp->b_flag  &= ~BFCHG;            /* Not changed        */
  374.     while ((lp=lforw(bp->b_linep)) != bp->b_linep)
  375.         lfree(lp);
  376.     bp->b_dotp  = bp->b_linep;        /* Fix "."        */
  377.     bp->b_doto  = 0;
  378.     bp->b_markp = NULL;            /* Invalidate "mark"    */
  379.     bp->b_marko = 0;
  380.     return (TRUE);
  381. }
  382.